package org.xmap.ui.effect;
import java.util.Random;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import org.xmap.ui.base.Window;
public final class Flame extends Window {
    private static Random random = new Random();
    private int dataLength;
    private int fireColorTable[];
    private final byte colorLevel = 100;
    private int fireData[]; // 存储了该点的颜色的索引
    public Flame(int leftUpX, int leftUpY, int width, int height) {
        super(leftUpX, leftUpY, width, height);
        this.dataLength = width * height;
        this.fireColorTable = new int[this.colorLevel]; // 颜色的索引值?
        this.fireData = new int[width * (height + 1)]; // 最下面两排是粒子源?
        // 初始化火焰颜色表
        this.initFireColor(0, this.colorLevel >> 2, 0, 255, // 红
                           0, 0, // 绿
                           0, 0); // 蓝
        this.initFireColor(this.colorLevel >> 2, this.colorLevel >> 1, 255, 255, // 红
                           0, 255, // 绿
                           0, 0); // 蓝
        this.initFireColor(this.colorLevel >> 1, this.colorLevel, 255, 255, // 红
                           255, 255, // 绿
                           0, 255); // 蓝
    }
    /*
     * 初始化颜色表
     */
    private void initFireColor(int begin, int end, int redBegin, int redEnd, int greenBegin, int greenEnd,
                               int blueBegin, int blueEnd) {
        int length = end - begin;
        int redLength = redEnd - redBegin;
        int greenLength = greenEnd - greenBegin;
        int blueLength = blueEnd - blueBegin;
        for (int i = 0; i < length; i++) {
            this.fireColorTable[begin + i] = 0xff000000 | redBegin + (i * redLength) / length << 16
                                             | greenBegin + (i * greenLength) / length << 8 |
                                             blueBegin + (i * blueLength)
                                             / length;
        }
    }
    public void draw(Graphics g) {
        g.drawImage(this.getImage(), 0, 0, Graphics.LEFT | Graphics.TOP);
    }
    public void update() {
        this.renderFire();
    }
    /**
     * 绘制火焰
     */
    public void renderFire() {
        for (int i = 5; i < this.getRect().width - 5; i++) {
            this.fireData[this.dataLength + i] = Math.abs(random.nextInt() % this.colorLevel);
        }
        for (int i = 1; i < this.dataLength - 1; i++) { // 这里对数组进行运算
            // 模糊处理
            int newValue = this.fireData[i]
                           + this.fireData[i + this.getRect().width - 1]
                           + this.fireData[i + this.getRect().width]
                           + this.fireData[i + this.getRect().width + 1] >> 2;
            newValue &= 0xffffffff;
            // 衰减因子, 这里可以加入随即衰减, 效果将更加逼真
            if (newValue > this.colorLevel / 2) {
                this.fireData[i] = newValue;
            } else if (newValue > this.colorLevel / 3) {
                this.fireData[i] = newValue;
            } else if (newValue > this.colorLevel / 4) {
                this.fireData[i] = newValue - 1;
            } else if (newValue > this.colorLevel / 10) {
                this.fireData[i] = newValue - 2;
            } else if (newValue > 1) {
                this.fireData[i] = newValue - 1;
            }
        }
    }
    public Image getImage() {
        int[] tempBA = new int[this.fireData.length];
        for (int i = 0; i < tempBA.length; i++) {
            tempBA[i] = this.fireColorTable[this.fireData[i]];
        }
        // Mask the black color
//        Fading.blend(tempBA, (short)128, true, 0x000000, false, 0x0);
        return Image.createRGBImage(tempBA, this.getRect().width, this.getRect().height, true);
    }
    public void drawFlame(Graphics g, Image background, boolean isBlend, short x, short y, int anchor) {
        if (isBlend) {
            int[] tempBA = new int[this.getRect().width * this.getRect().height];
            int imgX = (background.getWidth() - this.getRect().width) >> 1;
            int imgY = (background.getHeight() - this.getRect().height) >> 1;
            background.getRGB(tempBA, 0, this.getRect().width, imgX, imgY,
                              this.getRect().width, this.getRect().height);
            int[] tempBATarget = new int[this.fireData.length];
            for (int i = 0; i < tempBA.length; i++) {
                tempBATarget[i] = this.fireColorTable[this.fireData[i]];
            }
            Fading.fastBlend(tempBA, tempBA, tempBATarget); // Blend the background and fire
            Image tempImage = Image.createRGBImage(tempBA,
                    this.getRect().width, this.getRect().height, false);
            g.drawImage(tempImage, x, y, anchor);
        } else {
            g.drawImage(this.getImage(), x, y, anchor);
        }
    }
}
